﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Procure.Data.Context;
using umbraco.uicontrols;

namespace Procure.Web.attribute
{
    public partial class EditProduct : System.Web.UI.Page
    {
        private TabPage ProductTab = null;
        private TabPage AttributesTab = null;

        #region OnInit
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            ProcureDataContext context = DataFactory.GetDataContext();

            // first, populate the Product tab that has product information on it
            PopulateProductTab(context);

            // next, populate the attributes tab - this has product type attributes on it
            PopulateAttributesTab(context);
        } 
        #endregion

        #region PopulateProductTab
        private void PopulateProductTab(ProcureDataContext context)
        {
            // retrieve a list of product types from the database
            var productTypes = from pt in context.ProductTypes
                               orderby pt.Name
                               select new ListItem(pt.Name, pt.Id.ToString());
            // create the products tab
            ProductTab = tabControl.NewTabPage("Product");
            // add a save button to the products tab
            AddSaveButton(ProductTab);

            // add all of the product properties to the product tab
            AddTextBox(ref ProductTab, "ProductName", "Name");
            AddDropDown(ref ProductTab, "ProductType", "Product Type", productTypes);
            AddTextBox(ref ProductTab, "Description", "Description");
            AddTextBox(ref ProductTab, "StockNumber", "Stock Number");
            AddTextBox(ref ProductTab, "Weight", "Weight");
            AddTextBox(ref ProductTab, "Price", "Price");
            AddTextBox(ref ProductTab, "ShippingBase", "Shipping Base");
            AddTextBox(ref ProductTab, "ShippingUnit", "Shipping Per Unit");
            AddTextBox(ref ProductTab, "ShippingCase", "Products Per Case");
        } 
        #endregion

        #region PopulateAttributesTab
        private void PopulateAttributesTab(ProcureDataContext context)
        {
            // pull the product id from the query string
            int id = int.Parse(Request["id"]);
            // load the product from the database
            Procure.Data.Context.Product prod = context.Products.FirstOrDefault(p => p.Id == id);
            // create the attributes tab
            AttributesTab = tabControl.NewTabPage("Attributes");
            // add a save button to the attributes tab
            AddSaveButton(AttributesTab);

            // loop through all the attributes for this product's product type
            foreach (Procure.Data.Context.ProductTypeAttribute attribute in prod.ProductType.ProductTypeAttributes)
            {
                // load the attribute entity for this attribute - the linked one is incorrect
                Procure.Data.Context.Attribute attr = context.Attributes.FirstOrDefault(a => a.Id == attribute.AttributeId);
                // add an editor control to the tab for this attribute
                AddTextBox(ref AttributesTab, "tb" + attribute.AttributeId, attr.Name);
            }
        } 
        #endregion

        #region AddSaveButton
        private void AddSaveButton(TabPage tab)
        {
            // create a save button on the given tab
            ImageButton save = tab.Menu.NewImageButton();
            // populate the location to the image to use
            save.ImageUrl = umbraco.GlobalSettings.Path + "/images/editor/save.gif";
            // set alternate text for accessibility
            save.AlternateText = "Save";
            // attach a click handler
            save.Click += new ImageClickEventHandler(save_Click);
        }
        #endregion

        #region Add TextBox/DropDown
        #region AddTextBox
        private void AddTextBox(ref TabPage page, string InputId, string Name)
        {
            // create a new pane
            Pane pane = new Pane();
            // create a new property panel
            PropertyPanel ppanel = new PropertyPanel();
            // create a new textbox
            TextBox tb = new TextBox();
            // set the ids of the pane, prop panel and textbox
            pane.ID = InputId + "Pane";
            ppanel.ID = InputId + "Panel";
            ppanel.Text = Name;
            tb.ID = InputId;
            // set the appropriate input css classes
            tb.CssClass = "guiInputText guiInputStandardSize";
            // add the controls to their parents
            ppanel.Controls.Add(tb);
            pane.Controls.Add(ppanel);
            page.Controls.Add(pane);
        } 
        #endregion
        #region AddDropDown
        private void AddDropDown(ref TabPage page, string InputId, string Name, IEnumerable<ListItem> items)
        {
            // create a new pane
            Pane pane = new Pane();
            // create a new property panel
            PropertyPanel ppanel = new PropertyPanel();
            // create a new textbox
            DropDownList ddl = new DropDownList();
            // set the ids of the pane, prop panel and dropdown
            pane.ID = InputId + "Pane";
            ppanel.ID = InputId + "Panel";
            ppanel.Text = Name;
            ddl.ID = InputId;
            // loop through the list items provided and add them
            foreach (ListItem item in items)
                ddl.Items.Add(item);
            // set the appropriate input css classes
            ddl.CssClass = "guiInputText guiInputStandardSize";
            // add the controls to their parents
            ppanel.Controls.Add(ddl);

            pane.Controls.Add(ppanel);
            page.Controls.Add(pane);
        } 
        #endregion
        #endregion

        #region Page_Load
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ProcureDataContext context = DataFactory.GetDataContext();

                int id = int.Parse(Request["id"]);

                Procure.Data.Context.Product prod = context.Products.FirstOrDefault(p => p.Id == id);

                if (prod != null)
                {
                    SetControlText(ProductTab, "ProductName", prod.Name);
                    SetControlText(ProductTab, "Description", prod.Description);
                    SetControlText(ProductTab, "StockNumber", prod.StockNumber);
                    SetControlText(ProductTab, "Weight", prod.Weight.ToString("N3"));
                    SetControlText(ProductTab, "Price", prod.Price.ToString("N2"));
                    SetControlText(ProductTab, "ShippingBase", prod.ShippingBase.ToString("N2"));
                    SetControlText(ProductTab, "ShippingUnit", prod.ShippingUnit.ToString("N2"));
                    SetControlText(ProductTab, "ShippingCase", prod.ShippingCase.ToString("N0"));
                    SetControlSelected(ProductTab, "ProductType", prod.ProductTypeId.ToString());

                    SetAttributeValues(prod);
                }
            }
        }
        #endregion

        #region save_Click
        void save_Click(object sender, ImageClickEventArgs e)
        {
            int id = int.Parse(Request["id"]);
            ProcureDataContext context = DataFactory.GetDataContext();

            Product prod = context.Products.FirstOrDefault(a => a.Id == id);
            prod.Name = GetControlValue(ProductTab, "ProductName");
            prod.ProductTypeId = Convert.ToInt32(GetControlSelected(ProductTab, "ProductType"));
            prod.Description = GetControlValue(ProductTab, "Description");
            prod.StockNumber = GetControlValue(ProductTab, "StockNumber");
            prod.Weight = Convert.ToDecimal(GetControlValue(ProductTab, "Weight"));
            prod.Price = Convert.ToDecimal(GetControlValue(ProductTab, "Price"));
            prod.ShippingBase = Convert.ToDecimal(GetControlValue(ProductTab, "ShippingBase"));
            prod.ShippingUnit = Convert.ToDecimal(GetControlValue(ProductTab, "ShippingUnit"));
            prod.ShippingCase = Convert.ToInt32(GetControlValue(ProductTab, "ShippingCase"));

            SaveAttributeValues(ref prod);

            context.SubmitChanges();
        }

 
        #endregion

        #region SetAttributeValues
        private void SetAttributeValues(Product prod)
        {
            foreach (var productTypeAttribute in prod.ProductType.ProductTypeAttributes)
            {
                int attributeId = productTypeAttribute.AttributeId;
                ProductAttributeValue val = prod.ProductAttributeValues.FirstOrDefault(pav => pav.AttributeId == attributeId);
                if (val != null)
                    SetControlText(AttributesTab, "tb" + attributeId.ToString(), val.AttributeValue);
            }
        } 
        #endregion

        #region SaveAttributeValues
        private void SaveAttributeValues(ref Product prod)
        {

            foreach (var productTypeAttribute in prod.ProductType.ProductTypeAttributes)
            {
                int attributeId = productTypeAttribute.AttributeId;
                ProductAttributeValue val = prod.ProductAttributeValues.FirstOrDefault(pav => pav.AttributeId == attributeId);

                if (val == null)
                {
                    val = new ProductAttributeValue();
                    val.AttributeId = attributeId;
                    val.Product = prod;
                    prod.ProductAttributeValues.Add(val);
                }
                val.AttributeValue = GetControlValue(AttributesTab, "tb" + attributeId.ToString());
            }
        }  
        #endregion

        #region Get/Set Control Text
        #region SetControlText
        private void SetControlText(TabPage tab, string InputId, string Value)
        {
            Pane pane = tab.FindControl(InputId + "Pane") as Pane;
            PropertyPanel ppanel = pane.FindControl(InputId + "Panel") as PropertyPanel;
            TextBox tb = ppanel.FindControl(InputId) as TextBox;
            tb.Text = Value;
        } 
        #endregion
        #region GetControlValue
        private string GetControlValue(TabPage tab, string InputId)
        {
            Pane pane = tab.FindControl(InputId + "Pane") as Pane;
            PropertyPanel ppanel = pane.FindControl(InputId + "Panel") as PropertyPanel;
            TextBox tb = ppanel.FindControl(InputId) as TextBox;
            return tb.Text;
        } 
        #endregion
        #endregion

        #region Get/Set Control Selected
        #region SetControlSelected
        private void SetControlSelected(TabPage tab, string InputId, string SelectedValue)
        {
            Pane pane = tab.FindControl(InputId + "Pane") as Pane;
            PropertyPanel ppanel = pane.FindControl(InputId + "Panel") as PropertyPanel;
            ListControl lc = ppanel.FindControl(InputId) as ListControl;
            lc.SelectedValue = SelectedValue;
        } 
        #endregion

        #region GetControlSelected
        private string GetControlSelected(TabPage tab, string InputId)
        {
            Pane pane = tab.FindControl(InputId + "Pane") as Pane;
            PropertyPanel ppanel = pane.FindControl(InputId + "Panel") as PropertyPanel;
            ListControl lc = ppanel.FindControl(InputId) as ListControl;
            return (lc.SelectedValue);
        } 
        #endregion
        #endregion
    }
}